﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Noris.Tools.TraceVisualiser.Interface;
using Noris.Tools.TraceVisualiser.Support;
using Noris.Tools.TraceVisualiser.TraceData;
using Noris.Tools.TraceVisualiser.SqlParser;

namespace Noris.Tools.TraceVisualiser.Green.AplServer
{
    public class Func_SqlAnalyse : Func_SqlBase, IFunctionContextMenuItem
    {
		#region IPlugin Members
		/// <summary>
		/// Příznak, že Plugin je aktivní ve standardním běhu (tj. při běžném užiavtelském spuštění).
		/// Plně funkční pluginy tedy vrací true.
		/// Pluginy, které jsou ve vývoji, vrací false, takové jsou zobrazeny / spouštěny pouze v aplikaci, která běží v režimu Debug.
		/// </summary>
		bool IPlugin.Active { get { return false; } }
		#endregion
		#region IFunctionContextMenuItem Members
        bool IFunctionContextMenuItem.IsFunctionSuitableFor(FunctionContextMenuItemSuitableArgs args)
        {
            args.MenuItems.Add(new FunctionMenuItem(30, "Analýza četnosti SQL příkazů", true));
            return true;
        }
        bool IFunctionContextMenuItem.IsMenuItemEnabledFor(FunctionContextMenuItemRunArgs args)
        {
            List<EventSqlItem> sqlItems = GetSelectedSqlEvents(args);
            return (sqlItems.Count > 0);
        }
        void IFunctionContextMenuItem.Run(FunctionContextMenuItemRunArgs args)
        {
            List<EventSqlItem> sqlItems = GetSelectedSqlEvents(args);
            this._RunSqlAnalyse(sqlItems);
        }
        #endregion
        #region Práce s SQL dotazy
        private void _RunSqlAnalyse(List<EventSqlItem> sqlItems)
        {
            List<SqlAnalyseItem> result = new List<SqlAnalyseItem>();
            // Ze všech SQL příkazů si odvodím jejich zjednodušenou syntaxi:
            foreach (EventSqlItem sqlItem in sqlItems)
            {
                SqlAnalyseItem aItem = SqlAnalyseItem.CreateFromSqlCommand(sqlItem);
                result.Add(aItem);
            }
        }
        #endregion
    }
    #region SqlAnalyseItem : třída pro zachycení statistiky jednoho SQL příkazu
    /// <summary>
    /// SqlAnalyseItem : třída pro zachycení statistiky jednoho SQL příkazu
    /// </summary>
    internal class SqlAnalyseItem
    {
        public int SqlPId { get; set; }
        public string SqlCommand { get; set; }
        public string SqlParameters { get; set; }
        public int ResultRowCount { get; set; }
        public string ResultScalar { get; set; }
        public TimeRange Time { get; set; }
        /// <summary>
        /// SELECT ... FROM ... WHERE ... 
        /// Ve frázi WHERE jsou nahrazeny přímé hodnoty textem "DATA"
        /// </summary>
        public string SqlText1 { get; set; }
        /// <summary>
        /// SELECT ... FROM ... 
        /// Fráze WHERE je vynechána
        /// </summary>
        public string SqlText2 { get; set; }
        /// <summary>
        /// Skupina 0 = číslo skupiny SQL příkazů zcela identických
        /// </summary>
        public int Group0 { get; set; }
        /// <summary>
        /// Skupina 2 = číslo skupiny SQL příkazů se shodou v SqlText1 (SELECT FROM WHERE bez hodnot v podmínce)
        /// </summary>
        public int Group1 { get; set; }
        /// <summary>
        /// Skupina 2 = číslo skupiny SQL příkazů se shodou v SqlText2 (SELECT FROM)
        /// </summary>
        public int Group2 { get; set; }


        internal static SqlAnalyseItem CreateFromSqlCommand(EventSqlItem sqlItem)
        {
            SqlAnalyseItem aItem = new SqlAnalyseItem();
            aItem.SqlPId = sqlItem.SqlPId;
            aItem.SqlCommand = sqlItem.SqlCommand;
            aItem.SqlParameters = sqlItem.SqlParameters;
            aItem.ResultRowCount = sqlItem.ResultRowCount;
            aItem.ResultScalar = sqlItem.ResultScalar;
            aItem.Time = sqlItem.Time;

            using (SqlText parser = SqlText.CreateFromText(sqlItem.SqlCommand))
            {	// Rozparsuju daný SQL text na položky a z nich sestavím SQL příkazy:
                SqlParseCommand sqlCommand = parser.FindFirstCommand("SELECT");
                if (sqlCommand != null)
                {
                    string sql;

                    // Sestavím si konsolidovaný text pouze z některých keywordů (SELECT ... FROM ... ):
                    sql = "";
                    foreach (var item in sqlCommand.SyntaxItemsUsed)
                    {
                        if (item.KeyWord == "SELECT" || item.KeyWord == "FROM")
                            sql += (sql.Length > 0 ? " " : "") + item.KeyWord + " " + item.SqlContentCurrent;
                        else if (item.KeyWord == "WHERE")
                            sql += (sql.Length > 0 ? " " : "") + item.KeyWord + " " + item.SqlContentCurrent;
                    }
                    aItem.SqlText1 = sql;


                    // Sestavím si konsolidovaný text pouze z některých keywordů (SELECT ... FROM ... ):
                    sql = "";
                    foreach (var item in sqlCommand.SyntaxItemsUsed)
                    {
                        if (item.KeyWord == "SELECT" || item.KeyWord == "FROM")
                            sql += (sql.Length > 0 ? " " : "") + item.KeyWord + " " + item.SqlContentCurrent;
                    }
                    aItem.SqlText2 = sql;
                }
            }
            return aItem;
        }
    }
    #endregion
}
